// Utils.cpp
// 
// Copyright (c) Jason Sandys, 2009
//
// License: This code is released according to the 
// Microsoft Public License (Ms-PL) as documented at 
// http://osdappchooser.codeplex.com/license
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "Utils.h"

Error::Error (HRESULT hr)
{
	m_szMessage[0] = _T('\0');

	_com_error comError ( hr );

	PCTSTR message = comError.ErrorMessage();
	if ( message )
		_tcsncpy_s (m_szMessage, message, _countof (m_szMessage));

	m_szMessage[_countof(m_szMessage)-1] = _T('\0');
}

Error::Error (bool bIsSystemMsg, DWORD nID, ...)
{
	LPTSTR lpMsg;
	DWORD nFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER;
	LPVOID lpSource = 0;
	
	m_szMessage[0] = _T('\0');

	if (bIsSystemMsg)
		nFlags |= FORMAT_MESSAGE_FROM_SYSTEM;
	else
	{
		nFlags |= FORMAT_MESSAGE_FROM_STRING;
		lpSource = new _TCHAR[MAX_STRING_LENGTH];
		LoadString(AfxGetInstanceHandle (), nID, (LPTSTR)lpSource, MAX_STRING_LENGTH);
	}

	va_list args;
	va_start(args, nID);

	DWORD nSize = FormatMessage (nFlags, lpSource, nID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		(LPTSTR) &lpMsg, 0, &args);
	
	va_end(args);

	if (nSize > 0)
		_tcsncpy_s (m_szMessage, (LPTSTR)lpMsg, _countof (m_szMessage));

	if (lpSource != 0)
		delete lpSource;

	if (lpMsg != 0)
		LocalFree (lpMsg);

}

Error::Error (XmlParseError x)
{
	m_szMessage[0] = _T('\0');

	_TCHAR pszHexError[25];

	COLE2T pszMessage (x->reason);

	_ltot_s (x->errorCode, pszHexError, _countof (pszHexError), 16);

	_stprintf_s (m_szMessage, _countof (m_szMessage), _T("(0x%s) %s"), pszHexError, pszMessage);

}

Error::Error (XmlParseError x, PCTSTR pczContext)
{
	m_szMessage[0] = _T('\0');

	_TCHAR pszHexError[25];

	COLE2T pszMessage (x->reason);

	_ltot_s (x->errorCode, pszHexError, _countof (pszHexError), 16);

	_stprintf_s (m_szMessage, _countof (m_szMessage), _T("%s - (0x%s) %s"), pczContext, pszHexError, pszMessage);

}

/*Error::Error (PCTSTR format, ...)
{
	va_list args;
	va_start (args, format);

	_vstprintf_s (m_szMessage, format, args);

	va_end (args);
}
*/

CString FormatResourceString(DWORD dwStrID, ...)
{
	CString strMsg = _T (""); //Final resting place for the string returned

	if (dwStrID > 0)
	{
		LPTSTR lpMsg; //Pointer to the final string, space is allocated by the function called
		DWORD nFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING;
		LPVOID lpSource = new _TCHAR[MAX_STRING_LENGTH]; //Pointer to a string to load the resource string

		//Load the string from the resources based upon the ID passed in
		LoadString(AfxGetInstanceHandle (), dwStrID, (LPTSTR)lpSource, MAX_STRING_LENGTH);

		va_list args;
		va_start(args, dwStrID);

		//Format the resource string replacing substitution paramaters with the variable arg list passed in
		//Allocats memory for lpMsg automatically
		DWORD nSize = FormatMessage (nFlags, lpSource, dwStrID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
			(LPTSTR) &lpMsg, 0, &args);
		
		va_end(args);

		if (nSize > 0)
			strMsg = (LPTSTR)lpMsg;

		if (lpSource != 0)
			delete lpSource;

		if (lpMsg != 0)
			LocalFree (lpMsg);
	}

	return strMsg;
};

CString FormatResourceString(DWORD dwStrID, va_list* args)
{
	CString strMsg = _T (""); //Final resting place for the string returned

	if (dwStrID > 0)
	{
		LPTSTR lpMsg; //Pointer to the final string, space is allocated by the function called
		DWORD nFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING;
		LPVOID lpSource = new _TCHAR[MAX_STRING_LENGTH]; //Pointer to a string to load the resource string

		//Load the string from the resources based upon the ID passed in
		LoadString(AfxGetInstanceHandle (), dwStrID, (LPTSTR)lpSource, MAX_STRING_LENGTH);

		//Format the resource string replacing substitution paramaters with the variable arg list passed in
		//Allocats memory for lpMsg automatically
		DWORD nSize = FormatMessage (nFlags, lpSource, dwStrID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
			(LPTSTR) &lpMsg, 0, args);
		
		if (nSize > 0)
			strMsg = (LPTSTR)lpMsg;

		if (lpSource != 0)
			delete lpSource;

		if (lpMsg != 0)
			LocalFree (lpMsg);
	}

	return strMsg;
};


void merge_sets(IndexSet& set1, const IndexSet set2)
{
	for ( IndexSetInterator iter = set2.begin(); iter != set2.end(); ++iter)
		set1.insert (*iter);

}